package com.fingard.dsp.bank.directbank.jhbank02;

import com.fingard.constant.DateFormat2;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.directbank.jhbank02.utils.Decipher;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Calendar;
import java.util.Date;

/**
 * @ClassName JHBANK02Transaction
 * @Author Zhengzy
 * @Date 2019/12/2 14:50
 * @Version 1.0
 **/
public class JHBANK02Transaction extends JHBANK02Base implements ITransaction {
    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        String cer = getBankConfig().getValueAsString("certificatePath");
        String pfx = getBankConfig().getValueAsString("certificatePfxPath");
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        retAts.writeStart();
        String respCode = "";
        String respInfo = "";
        Calendar tmpCalFrom = Calendar.getInstance();
        tmpCalFrom.setTime(Format.Date8Format.parse(p_req7516.dateFrom));
        Calendar tmpCalTo = Calendar.getInstance();
        tmpCalTo.setTime(Format.Date8Format.parse(p_req7516.dateTo));
        int dateFrom = Integer.valueOf(p_req7516.dateFrom);
        int dateTo = Integer.valueOf(p_req7516.dateTo);
        try {
            while (dateFrom <= dateTo && StringHelper.isNullOrEmpty(respCode)) {
                Calendar tmpCalStep = Calendar.getInstance();
                tmpCalStep.setTime(tmpCalFrom.getTime());
                if (DateHelper.compareMonth(tmpCalFrom, tmpCalTo) == -1) {
                    tmpCalStep.set(Calendar.DAY_OF_MONTH, tmpCalFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpCalStep.setTime(tmpCalTo.getTime());
                }
                String lastTransDt = "";// 每页最大日期
                String lastTransSeq = "";// 每页最大流水
                while (true) {
                    XmlTextWriter xmlTextWriter = new XmlTextWriter();
                    JHBANK02Header header = new JHBANK02Header();
                    header.userid = bankFront.operator;
                    String nodeNo = getBankConfig().getValueAsString("nodeNo");
                    header.brchno = nodeNo;
                    header.servtp = "";
                    header.prcscd = "YQCZ02";
                    writeCommenHeader(xmlTextWriter, header);

                    xmlTextWriter.writeStartElement("Body");
                    xmlTextWriter.writeElementString("tellNo", bankFront.operator, true);// 操作员号
                    xmlTextWriter.writeElementString("nodeNo", nodeNo, true);// 机构标识
                    xmlTextWriter.writeElementString("tranCode", "YQCZ02", true);// 交易代码
                    xmlTextWriter.writeElementString("accountNo", p_req7516.actNum, true);// 账号
                    xmlTextWriter.writeElementString("subAccountNo", "", true);// 子账户
                    xmlTextWriter.writeElementString("currencyType", convertCurToBank(p_req7516.actCur), true);// 币种
                    xmlTextWriter.writeElementString("beginDate", Format.Date8Format.format(tmpCalFrom.getTime()), true);// 交易起始日期
                    xmlTextWriter.writeElementString("endDate", Format.Date8Format.format(tmpCalStep.getTime()), true);// 交易结束日期
                    xmlTextWriter.writeElementString("PageShowNum", "5", true);// 每页记录数
                    xmlTextWriter.writeElementString("lastTransDt", lastTransDt, true);// 每页最大日期
                    xmlTextWriter.writeElementString("lastTransSeq", lastTransSeq, true);// 每页最大流水
                    // tellNo+nodeNo+ tranCode+accountNo 字段值字符串连接后，私钥加密
                    String allStr = bankFront.operator + nodeNo + "YQCZ02" + p_req7516.actNum;
                    // 加签
                    String signStr = Decipher.sign(allStr, pfx);
                    xmlTextWriter.writeElementString("signature", signStr);
                    xmlTextWriter.writeEndDocument();

                    String[] bankResult = sendToBank(xmlTextWriter.toXmlString(), cer);
                    if (bankResult[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            // 得到密文、秘钥
                            String bankEncryptData = tmpBkReader.getFirstText("/root/encryptdata");
                            String bankEncryptKey = tmpBkReader.getFirstText("/root/encryptkey");
                            // 解密
                            String decryptData = decrypt(bankEncryptData, bankEncryptKey, pfx);
                            // 验签
                            if (checkBkSign(decryptData, cer)) {// 验签成功
                                StringBuilder tmpDecryptMsg = new StringBuilder();
                                XmlTextReader tmpReader = loadBankRespXmlReader(decryptData, tmpDecryptMsg);
                                String hostReturnCode = tmpReader.getFirstText("/root/hostReturnCode");
                                if ("0000".equals(hostReturnCode)) {
                                    int pageNum = 0;
                                    respCode = "0";
                                    while (tmpReader.read("/root/list/row")) {
                                        pageNum++;
                                        RetAtsTransDetail detail = new RetAtsTransDetail();
                                        detail.actNum = p_req7516.actNum;// 账号
                                        detail.accBal = tmpReader.readedXElement.getSingleTextNotNull("recAccountName");// 收方账户名称
                                        detail.cur = convertCurToATS(tmpReader.readedXElement.getSingleTextNotNull("currencyType"));// 币种
                                        detail.recAccName = tmpReader.readedXElement.getSingleTextNotNull("recAccount");// 收方账号
                                        detail.recAccNum = tmpReader.readedXElement.getSingleTextNotNull("payAccOpenBankNm");
                                        String dateStr = tmpReader.readedXElement.getSingleTextNotNull("transferDate");//yyyymmdd交易日期
                                        lastTransDt = dateStr;
                                        String timeStr = tmpReader.readedXElement.getSingleTextNotNull("transferTime");//hh:mm:ss:ssss交易时间
                                        Date date = new DateFormat2("yyyyMMdd hh:mm:ss").parse(dateStr + " " + timeStr.substring(0, 8));
                                        detail.tranDate = Format.Date10Format.format(date);
                                        detail.valueDate = detail.tranDate;// 起息日，格式yyyy-MM-dd，银行没有返回就用tranDate交易日期
                                        detail.tranTime = Format.DateTimeFormat.format(date);// 交易时间
                                        detail.usage = tmpReader.readedXElement.getSingleTextNotNull("Info");// 备注
                                        detail.abstr = pickupAbstr(detail.usage);
                                        detail.originator = tmpReader.readedXElement.getSingleTextNotNull("coreFlowNo");
                                        lastTransSeq = detail.originator;

                                        String cdFlag = tmpReader.readedXElement.getSingleTextNotNull("loanFlag");// 借贷标志
                                        String tranAmt = tmpReader.readedXElement.getSingleTextNotNull("payAccount");//借方发生额
                                        if ("D".equals(cdFlag)) {// 借
                                            int flag = 0;
                                            if (StringHelper.isNullOrEmpty(tranAmt) || "0.00".equals(tranAmt)) {
                                                tranAmt = tmpReader.readedXElement.getSingleTextNotNull("payAccountNm");//贷方发生额
                                                flag++;
                                            }
                                            if (tranAmt.indexOf("-") != -1) {
                                                flag++;
                                                tranAmt = tranAmt.substring(1);
                                            }
                                            detail.cdFlag = flag % 2 == 0 ? "1" : "2";
                                            detail.tranAmt = tranAmt;
                                        } else if ("C".equals(cdFlag)) {
                                            int flag = 1;
                                            if (StringHelper.isNullOrEmpty(tranAmt) || "0.00".equals(tranAmt)) {
                                                tranAmt = tmpReader.readedXElement.getSingleTextNotNull("payAccountNm");//贷方发生额
                                                flag++;
                                            }
                                            if (tranAmt.indexOf("-") != -1) {
                                                flag++;
                                                tranAmt = tranAmt.substring(1);
                                            }
                                            detail.cdFlag = flag % 2 == 0 ? "2" : "1";
                                            detail.tranAmt = tranAmt;
                                        } else {
                                            respCode = "-1";
                                            respInfo = "借贷标识: " + cdFlag + "无法识别";
                                            break;
                                        }
                                        retAts.writeRetDetail(detail);
                                    }
                                    // 返回报文中没有明细记录，表示当前月份查询完毕
                                    if (pageNum == 0 || "-1".equals(respCode)) {
                                        break;
                                    }
                                } else {
                                    // 与0000相对
                                    respCode = "-1";
                                    respInfo = tmpReader.getFirstText("/root/hostErrorMessage");
                                    break;
                                }
                            } else {
                                respCode = "-1";
                                respInfo = "验签不通过";
                                break;
                            }
                        } else {
                            respCode = "-1";
                            respInfo = tmpSbMsg.toString();
                            break;
                        }
                    } else {
                        respCode = "-1";
                        respInfo = bankResult[1];
                        break;
                    }

                }
                tmpCalFrom = tmpCalStep;
                tmpCalFrom.add(Calendar.DAY_OF_MONTH, 1);
                dateFrom = Integer.valueOf(Format.Date8Format.format(tmpCalFrom.getTime()));
            }
        } catch (Exception e) {
            respCode = "-1";
            respInfo = e.getMessage();
        }
        if ("-1".equals(respCode)) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(respCode);
            retAts.writeRespInfo(respInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        Req7516HisTrans p_req7516 = new Req7516HisTrans(p_req7515.reqHeader);
        p_req7516.actCur = p_req7515.actCur;
        p_req7516.actNum = p_req7515.actNum;
        p_req7516.actArea = p_req7515.actArea;
        Date date = new Date();
        p_req7516.dateFrom = Format.Date8Format.format(date);
        p_req7516.dateTo = Format.Date8Format.format(date);
        return d_7516_HisTrans(p_req7516);
    }
}
